package com.blog.cmrpersonalblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.cmrpersonalblog.dto.article.request.UserArticleQueryRequest;
import com.blog.cmrpersonalblog.dto.user.request.UserPasswordUpdateRequest;
import com.blog.cmrpersonalblog.dto.user.request.UserProfileUpdateRequest;
import com.blog.cmrpersonalblog.dto.user.response.AdminUserProfileResponse;
import com.blog.cmrpersonalblog.dto.user.response.UserInteractionResponse;
import com.blog.cmrpersonalblog.dto.user.response.UserProfileResponse;
import com.blog.cmrpersonalblog.dto.user.response.UserResponse;
import com.blog.cmrpersonalblog.entity.SysRole;
import com.blog.cmrpersonalblog.entity.SysUser;
import com.blog.cmrpersonalblog.entity.UserFollow;
import com.blog.cmrpersonalblog.entity.UserStats;
import com.blog.cmrpersonalblog.mapper.ArticleMapper;
import com.blog.cmrpersonalblog.mapper.UserActivityMapper;
import com.blog.cmrpersonalblog.mapper.UserCollectMapper;
import com.blog.cmrpersonalblog.mapper.UserFollowMapper;
import com.blog.cmrpersonalblog.mapper.UserLikeMapper;
import com.blog.cmrpersonalblog.mapper.UserStatsMapper;
import com.blog.cmrpersonalblog.service.NotificationService;
import com.blog.cmrpersonalblog.service.SysUserService;
import com.blog.cmrpersonalblog.service.UserActivityService;
import com.blog.cmrpersonalblog.service.UserProfileService;
import com.blog.cmrpersonalblog.utils.PasswordUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 用户详情服务实现类
 */
@Slf4j
@Service
public class UserProfileServiceImpl implements UserProfileService {

    @Resource
    private SysUserService sysUserService;

    @Resource
    private ArticleMapper articleMapper;

    @Resource
    private UserStatsMapper userStatsMapper;

    @Resource
    private UserFollowMapper userFollowMapper;

    @Resource
    private UserLikeMapper userLikeMapper;

    @Resource
    private UserCollectMapper userCollectMapper;

    @Resource
    private UserActivityMapper userActivityMapper;

    @Resource
    private UserActivityService userActivityService;

    @Resource
    private NotificationService notificationService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public UserProfileResponse getUserProfile(Long userId, Long currentUserId) {
        try {
            log.info("开始获取用户详情: userId={}, currentUserId={}", userId, currentUserId);

            // 获取用户基本信息
            UserResponse userInfo = sysUserService.getUserDetail(userId);
            if (userInfo == null) {
                log.warn("用户不存在: userId={}", userId);
                return null;
            }

            UserProfileResponse profile = new UserProfileResponse();
            BeanUtils.copyProperties(userInfo, profile);

            // 单独获取signature字段（因为UserResponse中没有这个字段）
            SysUser sysUser = sysUserService.getById(userId);
            if (sysUser != null) {
                profile.setSignature(sysUser.getSignature());
            }

            // 获取用户统计数据
            UserStats userStats = userStatsMapper.selectOne(
                new LambdaQueryWrapper<UserStats>().eq(UserStats::getUserId, userId)
            );

            log.info("查询用户统计数据: userId={}, userStats={}", userId, userStats);

            UserProfileResponse.UserStatsInfo statsInfo = new UserProfileResponse.UserStatsInfo();
            if (userStats != null) {
                // 验证统计数据准确性，如果不准确则异步重新计算
                validateAndRecalculateStatsIfNeeded(userId, userStats);

                // 手动设置每个字段，确保数据正确复制
                statsInfo.setArticleCount(userStats.getArticleCount() != null ? userStats.getArticleCount() : 0);
                statsInfo.setTotalViewCount(userStats.getTotalViewCount() != null ? userStats.getTotalViewCount() : 0L);
                statsInfo.setTotalLikeCount(userStats.getTotalLikeCount() != null ? userStats.getTotalLikeCount() : 0);
                statsInfo.setFollowerCount(userStats.getFollowerCount() != null ? userStats.getFollowerCount() : 0);
                statsInfo.setFollowingCount(userStats.getFollowingCount() != null ? userStats.getFollowingCount() : 0);

                log.info("用户统计数据已设置: userId={}, statsInfo={}", userId, statsInfo);
            } else {
                // 如果没有统计数据，尝试初始化并重新计算
                log.warn("用户统计数据不存在，开始初始化并重新计算: userId={}", userId);

                // 初始化用户统计记录
                userStatsMapper.initUserStats(userId);

                // 重新计算用户统计数据
                userStatsMapper.recalculateUserStats(userId);

                // 重新查询统计数据
                userStats = userStatsMapper.selectOne(
                    new LambdaQueryWrapper<UserStats>().eq(UserStats::getUserId, userId)
                );

                if (userStats != null) {
                    statsInfo.setArticleCount(userStats.getArticleCount() != null ? userStats.getArticleCount() : 0);
                    statsInfo.setTotalViewCount(userStats.getTotalViewCount() != null ? userStats.getTotalViewCount() : 0L);
                    statsInfo.setTotalLikeCount(userStats.getTotalLikeCount() != null ? userStats.getTotalLikeCount() : 0);
                    statsInfo.setFollowerCount(userStats.getFollowerCount() != null ? userStats.getFollowerCount() : 0);
                    statsInfo.setFollowingCount(userStats.getFollowingCount() != null ? userStats.getFollowingCount() : 0);

                    log.info("用户统计数据已重新计算: userId={}, articleCount={}, totalViewCount={}, followerCount={}",
                        userId, statsInfo.getArticleCount(), statsInfo.getTotalViewCount(), statsInfo.getFollowerCount());
                } else {
                    // 如果还是没有数据，设置为0
                    statsInfo.setArticleCount(0);
                    statsInfo.setTotalViewCount(0L);
                    statsInfo.setTotalLikeCount(0);
                    statsInfo.setFollowerCount(0);
                    statsInfo.setFollowingCount(0);

                    log.warn("用户统计数据初始化后仍为空，设置为默认值0: userId={}", userId);
                }
            }
            profile.setStats(statsInfo);

            // 获取最近发布的文章
            List<UserProfileResponse.ArticleInfo> recentArticles =
                articleMapper.selectRecentArticlesByUserId(userId, 5);
            profile.setRecentArticles(recentArticles);
            log.info("获取最近文章数量: userId={}, count={}", userId, recentArticles != null ? recentArticles.size() : 0);

            // 检查是否被当前用户关注
            if (currentUserId != null && !currentUserId.equals(userId)) {
                Boolean isFollowed = userFollowMapper.checkIsFollowing(currentUserId, userId);
                profile.setIsFollowed(isFollowed != null && isFollowed);
            } else {
                profile.setIsFollowed(false);
            }

            log.info("用户详情获取成功: userId={}", userId);
            return profile;
        } catch (Exception e) {
            log.error("获取用户详情失败: userId={}", userId, e);
            throw new RuntimeException("获取用户详情失败", e);
        }
    }

    @Override
    public IPage<UserProfileResponse.ArticleInfo> getUserArticles(UserArticleQueryRequest query) {
        try {
            Page<UserProfileResponse.ArticleInfo> page = new Page<>(query.getPage(), query.getSize());
            return articleMapper.selectUserArticlePage(page, query);
        } catch (Exception e) {
            log.error("查询用户文章失败: query={}", query, e);
            throw new RuntimeException("查询用户文章失败", e);
        }
    }

    @Override
    public IPage<UserProfileResponse.ArticleInfo> getUserArticleShowcase(Long userId, Integer page, Integer size, String sortType) {
        try {
            log.info("分页获取用户文章展示列表: userId={}, page={}, size={}, sortType={}", userId, page, size, sortType);

            // 参数校验
            if (page == null || page < 1) {
                page = 1;
            }
            if (size == null || size < 1) {
                size = 10;
            }
            if (sortType == null || sortType.trim().isEmpty()) {
                sortType = "latest";
            }

            // 验证sortType参数
            if (!"latest".equals(sortType) && !"hot".equals(sortType)) {
                log.warn("无效的排序类型: {}, 使用默认值latest", sortType);
                sortType = "latest";
            }

            // 创建分页对象
            Page<UserProfileResponse.ArticleInfo> pageObj = new Page<>(page, size);

            // 查询文章列表（避免N+1问题，使用子查询计算评论数）
            IPage<UserProfileResponse.ArticleInfo> result = articleMapper.selectUserArticleShowcasePage(pageObj, userId, sortType);

            log.info("获取用户文章展示列表成功: userId={}, total={}, pages={}", userId, result.getTotal(), result.getPages());

            return result;
        } catch (Exception e) {
            log.error("获取用户文章展示列表失败: userId={}", userId, e);
            throw new RuntimeException("获取用户文章展示列表失败", e);
        }
    }

    @Override
    public UserInteractionResponse getUserInteractions(Long userId, Long currentUserId) {
        try {
            UserInteractionResponse interactions = new UserInteractionResponse();

            // 获取关注的用户列表
            List<UserInteractionResponse.FollowingUserInfo> followingUsers = 
                userFollowMapper.selectFollowingUsers(userId, 20);
            interactions.setFollowingUsers(followingUsers);

            // 获取粉丝列表
            List<UserInteractionResponse.FollowerUserInfo> followers = 
                userFollowMapper.selectFollowers(userId, currentUserId, 20);
            interactions.setFollowers(followers);

            // 获取点赞的文章列表（最多20条）
            List<UserInteractionResponse.LikedArticleInfo> likedArticles = 
                userLikeMapper.selectUserLikedArticles(userId, 20);
            interactions.setLikedArticles(likedArticles);

            // 获取收藏的文章列表（最多20条）
            List<UserInteractionResponse.CollectedArticleInfo> collectedArticles = 
                userCollectMapper.selectUserCollectedArticles(userId, 20);
            interactions.setCollectedArticles(collectedArticles);

            return interactions;
        } catch (Exception e) {
            log.error("获取用户互动数据失败: userId={}", userId, e);
            throw new RuntimeException("获取用户互动数据失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean followUser(Long followerId, Long followingId, boolean isFollow) {
        try {
            if (followerId.equals(followingId)) {
                throw new RuntimeException("不能关注自己");
            }

            // 查询是否已存在关注记录
            UserFollow existingFollow = userFollowMapper.selectOne(
                new LambdaQueryWrapper<UserFollow>()
                    .eq(UserFollow::getFollowerId, followerId)
                    .eq(UserFollow::getFollowingId, followingId)
            );

            if (existingFollow == null) {
                if (isFollow) {
                    // 创建新的关注记录
                    UserFollow userFollow = new UserFollow();
                    userFollow.setFollowerId(followerId);
                    userFollow.setFollowingId(followingId);
                    userFollow.setStatus(1);
                    userFollow.setCreateTime(LocalDateTime.now());
                    userFollow.setUpdateTime(LocalDateTime.now());
                    userFollowMapper.insert(userFollow);
                }
            } else {
                // 更新关注状态
                existingFollow.setStatus(isFollow ? 1 : 0);
                existingFollow.setUpdateTime(LocalDateTime.now());
                userFollowMapper.updateById(existingFollow);
            }

            // 更新统计数据
            updateUserStats(followingId, "follower_count", isFollow ? 1 : -1);
            updateUserStats(followerId, "following_count", isFollow ? 1 : -1);

            // 发送新增粉丝通知
            if (isFollow) {
                try {
                    notificationService.sendFollowNotification(followerId, followingId);
                } catch (Exception e) {
                    log.error("发送关注通知失败: followerId={}, followingId={}", followerId, followingId, e);
                    // 通知发送失败不影响关注操作
                }
            }

            return true;
        } catch (Exception e) {
            log.error("关注/取消关注用户失败: followerId={}, followingId={}, isFollow={}", 
                     followerId, followingId, isFollow, e);
            throw new RuntimeException("关注操作失败", e);
        }
    }

    @Override
    public IPage<UserInteractionResponse.FollowerUserInfo> getUserFollowers(Long userId, Long currentUserId, Integer page, Integer size) {
        try {
            log.info("分页获取用户粉丝列表: userId={}, currentUserId={}, page={}, size={}", userId, currentUserId, page, size);

            Page<UserInteractionResponse.FollowerUserInfo> pageParam = new Page<>(page, size);
            IPage<UserInteractionResponse.FollowerUserInfo> result = userFollowMapper.selectFollowersPage(pageParam, userId, currentUserId);

            log.info("粉丝列表获取成功: userId={}, total={}, current={}", userId, result.getTotal(), result.getRecords().size());
            return result;
        } catch (Exception e) {
            log.error("获取用户粉丝列表失败: userId={}", userId, e);
            throw new RuntimeException("获取粉丝列表失败", e);
        }
    }

    @Override
    public IPage<UserInteractionResponse.FollowingUserInfo> getUserFollowing(Long userId, Long currentUserId, Integer page, Integer size) {
        try {
            log.info("分页获取用户关注列表: userId={}, currentUserId={}, page={}, size={}", userId, currentUserId, page, size);

            Page<UserInteractionResponse.FollowingUserInfo> pageParam = new Page<>(page, size);
            IPage<UserInteractionResponse.FollowingUserInfo> result = userFollowMapper.selectFollowingUsersPage(pageParam, userId, currentUserId);

            log.info("关注列表获取成功: userId={}, total={}, current={}", userId, result.getTotal(), result.getRecords().size());
            return result;
        } catch (Exception e) {
            log.error("获取用户关注列表失败: userId={}", userId, e);
            throw new RuntimeException("获取关注列表失败", e);
        }
    }

    @Override
    public IPage<UserInteractionResponse.LikedArticleInfo> getUserLikedArticles(Long userId, Integer page, Integer size) {
        try {
            log.info("分页获取用户点赞文章列表: userId={}, page={}, size={}", userId, page, size);

            Page<UserInteractionResponse.LikedArticleInfo> pageParam = new Page<>(page, size);
            IPage<UserInteractionResponse.LikedArticleInfo> result = userLikeMapper.selectUserLikedArticlesPage(pageParam, userId);

            log.info("点赞文章列表获取成功: userId={}, total={}, current={}", userId, result.getTotal(), result.getRecords().size());
            return result;
        } catch (Exception e) {
            log.error("获取用户点赞文章列表失败: userId={}", userId, e);
            throw new RuntimeException("获取点赞文章列表失败", e);
        }
    }

    @Override
    public IPage<UserInteractionResponse.CollectedArticleInfo> getUserCollectedArticles(Long userId, Integer page, Integer size) {
        try {
            log.info("分页获取用户收藏文章列表: userId={}, page={}, size={}", userId, page, size);

            Page<UserInteractionResponse.CollectedArticleInfo> pageParam = new Page<>(page, size);
            IPage<UserInteractionResponse.CollectedArticleInfo> result = userCollectMapper.selectUserCollectedArticlesPage(pageParam, userId);

            log.info("收藏文章列表获取成功: userId={}, total={}, current={}", userId, result.getTotal(), result.getRecords().size());
            return result;
        } catch (Exception e) {
            log.error("获取用户收藏文章列表失败: userId={}", userId, e);
            throw new RuntimeException("获取收藏文章列表失败", e);
        }
    }

    @Override
    public void initUserStats(Long userId) {
        try {
            userStatsMapper.initUserStats(userId);
        } catch (Exception e) {
            log.error("初始化用户统计数据失败: userId={}", userId, e);
            throw new RuntimeException("初始化用户统计数据失败", e);
        }
    }

    @Override
    public void updateUserStats(Long userId, String field, Integer increment) {
        try {
            userStatsMapper.updateUserStats(userId, field, increment);
        } catch (Exception e) {
            log.error("更新用户统计数据失败: userId={}, field={}, increment={}", 
                     userId, field, increment, e);
            throw new RuntimeException("更新用户统计数据失败", e);
        }
    }

    @Override
    public void recalculateUserStats(Long userId) {
        try {
            userStatsMapper.recalculateUserStats(userId);
        } catch (Exception e) {
            log.error("重新计算用户统计数据失败: userId={}", userId, e);
            throw new RuntimeException("重新计算用户统计数据失败", e);
        }
    }

    // ==================== 后台管理专用方法实现 ====================

    @Override
    public AdminUserProfileResponse getAdminUserProfile(Long userId) {
        try {
            AdminUserProfileResponse response = new AdminUserProfileResponse();

            // 获取用户基本信息
            UserResponse userInfo = sysUserService.getUserDetail(userId);
            if (userInfo == null) {
                return null;
            }

            AdminUserProfileResponse.UserBasicInfo basicInfo = new AdminUserProfileResponse.UserBasicInfo();
            BeanUtils.copyProperties(userInfo, basicInfo);

            // 手动处理角色名称转换（从String转为List<String>）
            if (userInfo.getRoles() != null && !userInfo.getRoles().isEmpty()) {
                List<String> roleNameList = userInfo.getRoles().stream()
                    .map(SysRole::getRoleName)
                    .collect(java.util.stream.Collectors.toList());
                basicInfo.setRoleNames(roleNameList);
            } else {
                basicInfo.setRoleNames(java.util.Collections.emptyList());
            }

            response.setBasicInfo(basicInfo);

            // 获取用户统计数据
            UserStats userStats = userStatsMapper.selectOne(
                new LambdaQueryWrapper<UserStats>().eq(UserStats::getUserId, userId)
            );

            AdminUserProfileResponse.UserStatsInfo statsInfo = new AdminUserProfileResponse.UserStatsInfo();
            if (userStats != null) {
                BeanUtils.copyProperties(userStats, statsInfo);

                // 添加更多统计数据（草稿数、已删除数等）
                Map<String, Object> additionalStats = getAdditionalUserStats(userId);
                statsInfo.setDraftCount((Integer) additionalStats.get("draftCount"));
                statsInfo.setDeletedCount((Integer) additionalStats.get("deletedCount"));
                statsInfo.setReceivedLikeCount((Integer) additionalStats.get("receivedLikeCount"));
                statsInfo.setGivenLikeCount((Integer) additionalStats.get("givenLikeCount"));
                statsInfo.setCommentGivenCount((Integer) additionalStats.get("commentGivenCount"));
                statsInfo.setCommentReceivedCount((Integer) additionalStats.get("commentReceivedCount"));
            } else {
                // 如果没有统计数据，初始化一条记录
                log.info("用户{}没有统计数据，正在初始化...", userId);
                userStatsMapper.initUserStats(userId);

                // 重新查询
                userStats = userStatsMapper.selectOne(
                    new LambdaQueryWrapper<UserStats>().eq(UserStats::getUserId, userId)
                );

                if (userStats != null) {
                    BeanUtils.copyProperties(userStats, statsInfo);

                    // 添加更多统计数据
                    Map<String, Object> additionalStats = getAdditionalUserStats(userId);
                    statsInfo.setDraftCount((Integer) additionalStats.get("draftCount"));
                    statsInfo.setDeletedCount((Integer) additionalStats.get("deletedCount"));
                    statsInfo.setReceivedLikeCount((Integer) additionalStats.get("receivedLikeCount"));
                    statsInfo.setGivenLikeCount((Integer) additionalStats.get("givenLikeCount"));
                    statsInfo.setCommentGivenCount((Integer) additionalStats.get("commentGivenCount"));
                    statsInfo.setCommentReceivedCount((Integer) additionalStats.get("commentReceivedCount"));
                }
            }
            response.setStats(statsInfo);

            // 获取内容发布信息
            AdminUserProfileResponse.ContentInfo contentInfo = getUserContentInfo(userId);
            response.setContentInfo(contentInfo);

            // 获取互动行为数据
            AdminUserProfileResponse.InteractionInfo interactionInfo =
                userActivityService.getUserInteractionInfo(userId, 30);
            response.setInteractionInfo(interactionInfo);

            // 获取安全信息
            AdminUserProfileResponse.SecurityInfo securityInfo =
                userActivityService.getUserSecurityInfo(userId);
            response.setSecurityInfo(securityInfo);

            // 获取最近活动记录
            List<AdminUserProfileResponse.ActivityRecord> recentActivities =
                userActivityService.getRecentActivities(userId, 20);
            response.setRecentActivities(recentActivities);

            return response;
        } catch (Exception e) {
            log.error("获取后台用户详情失败: userId={}", userId, e);
            throw new RuntimeException("获取后台用户详情失败", e);
        }
    }

    @Override
    public AdminUserProfileResponse.ContentInfo getUserContentInfo(Long userId) {
        try {
            AdminUserProfileResponse.ContentInfo contentInfo = new AdminUserProfileResponse.ContentInfo();

            // 查询用户文章的发布统计信息
            Map<String, Object> publishStats = articleMapper.selectUserPublishStats(userId);

            if (publishStats != null) {
                contentInfo.setFirstPublishTime((LocalDateTime) publishStats.get("firstPublishTime"));
                contentInfo.setLastPublishTime((LocalDateTime) publishStats.get("lastPublishTime"));

                // 计算平均值 - 修复类型转换问题
                Object totalArticlesObj = publishStats.get("totalArticles");
                Object totalViewsObj = publishStats.get("totalViews");
                Object totalLikesObj = publishStats.get("totalLikes");
                Object publishDaysObj = publishStats.get("publishDays");

                // 安全的类型转换
                Long totalArticles = convertToLong(totalArticlesObj);
                Long totalViews = convertToLong(totalViewsObj);
                Long totalLikes = convertToLong(totalLikesObj);
                Long publishDays = convertToLong(publishDaysObj);

                if (totalArticles != null && totalArticles > 0) {
                    contentInfo.setAvgViewsPerArticle(totalViews != null ? totalViews.doubleValue() / totalArticles : 0.0);
                    contentInfo.setAvgLikesPerArticle(totalLikes != null ? totalLikes.doubleValue() / totalArticles : 0.0);
                } else {
                    contentInfo.setAvgViewsPerArticle(0.0);
                    contentInfo.setAvgLikesPerArticle(0.0);
                }

                // 计算发布频率（文章数/天数）
                if (publishDays != null && publishDays > 0) {
                    contentInfo.setPublishFrequency(totalArticles != null ? totalArticles.intValue() / publishDays.intValue() : 0);
                } else {
                    contentInfo.setPublishFrequency(0);
                }
            } else {
                contentInfo.setFirstPublishTime(null);
                contentInfo.setLastPublishTime(null);
                contentInfo.setAvgViewsPerArticle(0.0);
                contentInfo.setAvgLikesPerArticle(0.0);
                contentInfo.setPublishFrequency(0);
            }

            // 获取分类统计
            List<Map<String, Object>> categoryStatsData = articleMapper.selectUserCategoryStats(userId);
            List<AdminUserProfileResponse.CategoryStats> categoryStats = convertToCategoryStats(categoryStatsData);
            contentInfo.setCategoryStats(categoryStats);

            // 获取热门标签
            List<Map<String, Object>> topTagsData = articleMapper.selectUserTopTags(userId, 10);
            List<String> topTags = convertToTopTags(topTagsData);
            contentInfo.setTopTags(topTags);

            return contentInfo;
        } catch (Exception e) {
            log.error("获取用户内容信息失败: userId={}", userId, e);
            throw new RuntimeException("获取用户内容信息失败", e);
        }
    }

    /**
     * 获取用户额外统计数据
     * @param userId 用户ID
     * @return 额外统计数据
     */
    private Map<String, Object> getAdditionalUserStats(Long userId) {
        Map<String, Object> stats = new HashMap<>();

        try {
            // 查询草稿数
            Integer draftCount = articleMapper.countUserDrafts(userId);
            stats.put("draftCount", draftCount != null ? draftCount : 0);

            // 查询已删除文章数
            Integer deletedCount = articleMapper.countUserDeletedArticles(userId);
            stats.put("deletedCount", deletedCount != null ? deletedCount : 0);

            // 查询收到的点赞数（文章被点赞） - 修复类型转换
            Integer receivedLikeCount = articleMapper.countUserReceivedLikes(userId);
            stats.put("receivedLikeCount", receivedLikeCount != null ? receivedLikeCount : 0);

            // 查询给出的点赞数（用户点赞其他文章）
            Integer givenLikeCount = articleMapper.countUserGivenLikes(userId);
            stats.put("givenLikeCount", givenLikeCount != null ? givenLikeCount : 0);

            // 查询发出的评论数
            Integer commentGivenCount = articleMapper.countUserGivenComments(userId);
            stats.put("commentGivenCount", commentGivenCount != null ? commentGivenCount : 0);

            // 查询收到的评论数（文章被评论）
            Integer commentReceivedCount = articleMapper.countUserReceivedComments(userId);
            stats.put("commentReceivedCount", commentReceivedCount != null ? commentReceivedCount : 0);

        } catch (Exception e) {
            log.warn("获取用户额外统计数据失败: userId={}, error={}", userId, e.getMessage());
            // 设置默认值
            stats.put("draftCount", 0);
            stats.put("deletedCount", 0);
            stats.put("receivedLikeCount", 0);
            stats.put("givenLikeCount", 0);
            stats.put("commentGivenCount", 0);
            stats.put("commentReceivedCount", 0);
        }

        return stats;
    }

    /**
     * 转换分类统计数据
     * @param categoryStatsData 原始分类统计数据
     * @return 转换后的分类统计列表
     */
    private List<AdminUserProfileResponse.CategoryStats> convertToCategoryStats(List<Map<String, Object>> categoryStatsData) {
        if (categoryStatsData == null || categoryStatsData.isEmpty()) {
            return List.of();
        }

        return categoryStatsData.stream().map(data -> {
            AdminUserProfileResponse.CategoryStats stats = new AdminUserProfileResponse.CategoryStats();
            stats.setCategoryName((String) data.get("categoryName"));

            // 安全的类型转换
            Object articleCountObj = data.get("articleCount");
            Object totalViewsObj = data.get("totalViews");
            Object totalLikesObj = data.get("totalLikes");

            stats.setArticleCount(convertToLong(articleCountObj) != null ? convertToLong(articleCountObj).intValue() : 0);
            stats.setTotalViews(convertToLong(totalViewsObj) != null ? convertToLong(totalViewsObj) : 0L);
            stats.setTotalLikes(convertToLong(totalLikesObj) != null ? convertToLong(totalLikesObj).intValue() : 0);

            return stats;
        }).collect(java.util.stream.Collectors.toList());
    }

    /**
     * 转换热门标签数据
     * @param topTagsData 原始标签数据
     * @return 转换后的标签名称列表
     */
    private List<String> convertToTopTags(List<Map<String, Object>> topTagsData) {
        if (topTagsData == null || topTagsData.isEmpty()) {
            return List.of();
        }

        return topTagsData.stream()
            .map(data -> (String) data.get("tagName"))
            .filter(tagName -> tagName != null && !tagName.trim().isEmpty())
            .collect(java.util.stream.Collectors.toList());
    }

    /**
     * 安全的类型转换为Long
     * @param obj 待转换的对象
     * @return Long值，转换失败返回null
     */
    private Long convertToLong(Object obj) {
        if (obj == null) {
            return null;
        }

        if (obj instanceof Long) {
            return (Long) obj;
        } else if (obj instanceof Integer) {
            return ((Integer) obj).longValue();
        } else if (obj instanceof Number) {
            return ((Number) obj).longValue();
        } else if (obj instanceof String) {
            try {
                return Long.parseLong((String) obj);
            } catch (NumberFormatException e) {
                log.warn("无法将字符串转换为Long: {}", obj);
                return null;
            }
        }

        log.warn("无法将对象转换为Long: {} (类型: {})", obj, obj.getClass().getSimpleName());
        return null;
    }

    @Override
    public void recordUserActivity(Long userId, String activityType, String description,
                                  Long targetId, String targetType, String ipAddress,
                                  String userAgent, String result) {
        // 兼容旧的字符串类型，转换为枚举类型
        try {
            com.blog.cmrpersonalblog.enums.ActivityType type =
                com.blog.cmrpersonalblog.enums.ActivityType.fromCode(activityType);
            if (type != null) {
                userActivityService.recordActivity(userId, type, description,
                                                  targetId, targetType, ipAddress, userAgent, result, null);
            } else {
                log.warn("未知的活动类型: {}", activityType);
            }
        } catch (Exception e) {
            log.warn("记录用户活动失败: userId={}, activityType={}, error={}",
                    userId, activityType, e.getMessage());
        }
    }

    @Override
    public AdminUserProfileResponse.InteractionInfo getUserActivityStats(Long userId, Integer days) {
        try {
            return userActivityMapper.selectUserInteractionInfo(userId);
        } catch (Exception e) {
            log.warn("获取用户活动统计失败，可能是user_activity表不存在: userId={}, days={}, error={}",
                    userId, days, e.getMessage());
            // 返回默认值而不是抛出异常
            AdminUserProfileResponse.InteractionInfo defaultInfo = new AdminUserProfileResponse.InteractionInfo();
            defaultInfo.setLastLoginTime(null);
            defaultInfo.setLastActiveTime(null);
            defaultInfo.setLoginDays(0);
            defaultInfo.setAvgDailyActiveTime(0.0);
            defaultInfo.setTotalSessions(0);
            defaultInfo.setActiveTimeRanges(List.of());
            return defaultInfo;
        }
    }

    @Override
    public Integer cleanExpiredActivities(Integer days) {
        try {
            LocalDateTime beforeTime = LocalDateTime.now().minusDays(days);
            return userActivityMapper.deleteExpiredActivities(beforeTime);
        } catch (Exception e) {
            log.warn("清理过期活动记录失败: days={}, error={}",
                    days, e.getMessage());
            // 返回0而不是抛出异常
            return 0;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserProfile(Long userId, UserProfileUpdateRequest updateRequest) {
        try {
            log.info("更新用户个人信息: userId={}", userId);

            // 检查用户是否存在
            SysUser existingUser = sysUserService.getById(userId);
            if (existingUser == null) {
                throw new RuntimeException("用户不存在");
            }

            // 检查邮箱是否被其他用户使用
            if (StringUtils.hasText(updateRequest.getEmail()) &&
                !updateRequest.getEmail().equals(existingUser.getEmail())) {
                SysUser emailUser = sysUserService.getUserByEmail(updateRequest.getEmail());
                if (emailUser != null && !emailUser.getUserId().equals(userId)) {
                    throw new RuntimeException("邮箱已被其他用户使用");
                }
            }

            // 检查手机号是否被其他用户使用
            if (StringUtils.hasText(updateRequest.getPhonenumber()) &&
                !updateRequest.getPhonenumber().equals(existingUser.getPhonenumber())) {
                LambdaQueryWrapper<SysUser> phoneQuery = new LambdaQueryWrapper<>();
                phoneQuery.eq(SysUser::getPhonenumber, updateRequest.getPhonenumber())
                         .ne(SysUser::getUserId, userId);
                SysUser phoneUser = sysUserService.getOne(phoneQuery);
                if (phoneUser != null) {
                    throw new RuntimeException("手机号已被其他用户使用");
                }
            }

            // 更新用户信息
            SysUser updateUser = new SysUser();
            updateUser.setUserId(userId);

            if (StringUtils.hasText(updateRequest.getNickName())) {
                updateUser.setNickName(updateRequest.getNickName());
            }
            if (StringUtils.hasText(updateRequest.getEmail())) {
                updateUser.setEmail(updateRequest.getEmail());
                // 如果邮箱发生变化，重置邮箱验证状态
                if (!updateRequest.getEmail().equals(existingUser.getEmail())) {
                    updateUser.setEmailVerified(0);
                    updateUser.setEmailVerifiedTime(null);
                }
            }
            if (StringUtils.hasText(updateRequest.getPhonenumber())) {
                updateUser.setPhonenumber(updateRequest.getPhonenumber());
            }
            if (StringUtils.hasText(updateRequest.getAvatar())) {
                updateUser.setAvatar(updateRequest.getAvatar());
            }
            if (StringUtils.hasText(updateRequest.getSex())) {
                updateUser.setSex(updateRequest.getSex());
            }
            if (updateRequest.getSignature() != null) {
                updateUser.setSignature(updateRequest.getSignature());
            }

            updateUser.setUpdateTime(LocalDateTime.now());
            updateUser.setUpdateBy(String.valueOf(userId));

            boolean success = sysUserService.updateById(updateUser);
            if (success) {
                log.info("用户个人信息更新成功: userId={}", userId);
            } else {
                log.error("用户个人信息更新失败: userId={}", userId);
            }

            return success;
        } catch (Exception e) {
            log.error("更新用户个人信息失败: userId={}, error={}", userId, e.getMessage());
            throw new RuntimeException("更新个人信息失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserPassword(Long userId, UserPasswordUpdateRequest passwordRequest) {
        try {
            log.info("修改用户密码: userId={}", userId);

            // 验证新密码和确认密码是否一致
            if (!passwordRequest.getNewPassword().equals(passwordRequest.getConfirmPassword())) {
                throw new RuntimeException("新密码和确认密码不一致");
            }

            // 检查用户是否存在
            SysUser existingUser = sysUserService.getById(userId);
            if (existingUser == null) {
                throw new RuntimeException("用户不存在");
            }

            // 验证当前密码是否正确
            if (!sysUserService.verifyPassword(existingUser, passwordRequest.getCurrentPassword())) {
                throw new RuntimeException("当前密码不正确");
            }

            // 检查新密码是否与当前密码相同
            if (sysUserService.verifyPassword(existingUser, passwordRequest.getNewPassword())) {
                throw new RuntimeException("新密码不能与当前密码相同");
            }

            // 更新密码
            SysUser updateUser = new SysUser();
            updateUser.setUserId(userId);
            updateUser.setPassword(PasswordUtils.sha256EncryptWithUserSalt(
                passwordRequest.getNewPassword(), existingUser.getUserName()));
            updateUser.setUpdateTime(LocalDateTime.now());
            updateUser.setUpdateBy(String.valueOf(userId));

            boolean success = sysUserService.updateById(updateUser);
            if (success) {
                log.info("用户密码修改成功: userId={}", userId);
            } else {
                log.error("用户密码修改失败: userId={}", userId);
            }

            return success;
        } catch (Exception e) {
            log.error("修改用户密码失败: userId={}, error={}", userId, e.getMessage());
            throw new RuntimeException("修改密码失败：" + e.getMessage());
        }
    }

    /**
     * 验证统计数据准确性，如果不准确则异步重新计算
     * 使用Redis缓存标记，避免频繁重新计算（每个用户每小时最多重新计算一次）
     */
    private void validateAndRecalculateStatsIfNeeded(Long userId, UserStats userStats) {
        try {
            // 检查Redis缓存标记，避免频繁重新计算
            String cacheKey = "user:stats:recalculate:" + userId;
            Boolean hasRecalculated = redisTemplate.hasKey(cacheKey);

            if (Boolean.TRUE.equals(hasRecalculated)) {
                // 1小时内已经重新计算过，跳过
                return;
            }

            // 快速验证：检查关注数和粉丝数是否明显不准确
            // 只验证这两个字段，因为它们最容易出现不一致（用户可能直接操作数据库）
            boolean needRecalculate = false;

            // 检查关注数
            Integer followingCount = userStats.getFollowingCount();
            if (followingCount != null && followingCount > 0) {
                // 只有当统计数大于0时才验证，避免不必要的查询
                Long actualFollowingCount = userFollowMapper.selectCount(
                    new LambdaQueryWrapper<UserFollow>()
                        .eq(UserFollow::getFollowerId, userId)
                        .eq(UserFollow::getStatus, 1)
                );

                if (!followingCount.equals(actualFollowingCount.intValue())) {
                    log.warn("用户关注数不准确: userId={}, cached={}, actual={}",
                        userId, followingCount, actualFollowingCount);
                    needRecalculate = true;
                }
            }

            // 检查粉丝数
            if (!needRecalculate) {
                Integer followerCount = userStats.getFollowerCount();
                if (followerCount != null && followerCount > 0) {
                    Long actualFollowerCount = userFollowMapper.selectCount(
                        new LambdaQueryWrapper<UserFollow>()
                            .eq(UserFollow::getFollowingId, userId)
                            .eq(UserFollow::getStatus, 1)
                    );

                    if (!followerCount.equals(actualFollowerCount.intValue())) {
                        log.warn("用户粉丝数不准确: userId={}, cached={}, actual={}",
                            userId, followerCount, actualFollowerCount);
                        needRecalculate = true;
                    }
                }
            }

            // 如果需要重新计算，异步执行
            if (needRecalculate) {
                log.info("检测到用户统计数据不准确，触发异步重新计算: userId={}", userId);
                asyncRecalculateUserStats(userId);

                // 设置Redis缓存标记，1小时过期
                redisTemplate.opsForValue().set(cacheKey, true, 1, TimeUnit.HOURS);
            }
        } catch (Exception e) {
            // 验证失败不影响主流程
            log.error("验证用户统计数据失败: userId={}", userId, e);
        }
    }

    /**
     * 异步重新计算用户统计数据
     */
    @Async
    public void asyncRecalculateUserStats(Long userId) {
        try {
            log.info("开始异步重新计算用户统计数据: userId={}", userId);
            userStatsMapper.recalculateUserStats(userId);
            log.info("异步重新计算用户统计数据完成: userId={}", userId);
        } catch (Exception e) {
            log.error("异步重新计算用户统计数据失败: userId={}", userId, e);
        }
    }
}
